package gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableColumn;
import javax.swing.table.TableRowSorter;

import client.DownloadTableModel;
import client.Log;

public abstract class ClientPanel extends JPanel {

	public ClientPanel() {
		super(new BorderLayout());

		init();

		Log.setOutput(mLog);
	}

	public void setDirectoryModels(DefaultListModel remoteModel) {
		mRemoteList.setModel(remoteModel);
	}

	private void init() {
		JSplitPane splitPaneHorizontal = new JSplitPane(
				JSplitPane.HORIZONTAL_SPLIT, getLeftPanel(), getRightPanel());
		splitPaneHorizontal.setOneTouchExpandable(true);
		splitPaneHorizontal.setDividerLocation(200);
		splitPaneHorizontal.setDividerSize(4);

		JSplitPane splitPaneVertical = new JSplitPane(
				JSplitPane.VERTICAL_SPLIT, splitPaneHorizontal,
				wrapWithScrollPane(getLog()));
		splitPaneVertical.setOneTouchExpandable(true);
		splitPaneVertical.setDividerLocation(200);
		splitPaneVertical.setDividerSize(4);

		add(splitPaneVertical, BorderLayout.CENTER);
	}

	public JTextArea getLog() {
		mLog = new JTextArea();

		mLog.setFont(new Font("Arial", Font.PLAIN, 12));
		mLog.setRows(4);
		mLog.setEditable(false);

		return mLog;
	}

	public void log(String text) {
		if (mLog.getDocument().getLength() == 0) {
			mLog.append(text);
		} else {
			mLog.append("\n" + text);
		}
		mLog.setCaretPosition(mLog.getDocument().getLength());
	}

	public JList getRemoteList() {
		if (mRemoteList == null) {
			mRemoteList = new JList();
			mRemoteList
					.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
			mRemoteList.setVisibleRowCount(-1);

			mRemoteList.setMinimumSize(new Dimension(250, 250));
			mRemoteList.setPreferredSize(new Dimension(250, 250));

			mRemoteList.addListSelectionListener(mRemoteListSelectionListener);
		}
		return mRemoteList;
	}

	public JTable getDownloadTable() {
		if (mDownloadTable == null) {
			mTableModel = new DownloadTableModel();
			sorter = new TableRowSorter<DownloadTableModel>(mTableModel);
			mDownloadTable = new JTable(mTableModel);
			mDownloadTable.setRowSorter(sorter);
			mDownloadTable.setFillsViewportHeight(true);
			mDownloadTable.setPreferredScrollableViewportSize(new Dimension(
					300, 150));
			mDownloadTable
					.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

			TableColumn column = null;
			for (int i = 0; i < mDownloadTable.getColumnCount(); i++) {
				column = mDownloadTable.getColumnModel().getColumn(i);
				if (i == 0) {
					column.setPreferredWidth(200); // third column is bigger
				} else {
					column.setPreferredWidth(75);
				}
			}

		}
		return mDownloadTable;
	}

	private JPanel getLeftPanel() {
		JPanel panel = new JPanel(new BorderLayout());

		panel.add(getRemoteAddressBar(), BorderLayout.NORTH);
		panel.add(wrapWithScrollPane(getRemoteList()), BorderLayout.CENTER);
		panel.add(getRight_bottomPanel(), BorderLayout.SOUTH);

		return panel;
	}

	private JPanel getRightPanel() {
		JPanel panel = new JPanel(new BorderLayout());

		panel.add(new JScrollPane(getDownloadTable()), BorderLayout.CENTER);
		JPanel panel2 = new JPanel();
		JButton button = new JButton("Pause");
		button.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				pauseClick();
			}

		});
		panel2.add(button);
		button = new JButton("Resume");
		button.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				resumeClick();
			}

		});
		panel2.add(button);

		panel.add(panel2, BorderLayout.SOUTH);

		return panel;
	}

	private JPanel getRight_bottomPanel() {
		JPanel panel = new JPanel();

		mDownloadButton = getDownloadButton();
		panel.add(mDownloadButton);

		return panel;
	}

	protected void updateRemoteAddress(String address) {
		mSearch.setText(address);
	}

	private JPanel getRemoteAddressBar() {
		JPanel panel = new JPanel(new BorderLayout());

		mSearch = new JTextField();
		mSearch.addKeyListener(new KeyListener() {

			@Override
			public void keyPressed(KeyEvent arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void keyReleased(KeyEvent arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void keyTyped(KeyEvent e) {
				if (e.getKeyChar() == '\n') {
					search(getQuery());
				}
			}

		});
		JButton button;

		button = new JButton("GO");
		button.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				search(getQuery());
			}

		});

		panel.add(mSearch, BorderLayout.CENTER);
		panel.add(button, BorderLayout.EAST);

		return panel;
	}

	private String getQuery() {
		return mSearch.getText();
	}

	private JButton getDownloadButton() {
		JButton button = new JButton("Download");
		button.setEnabled(false);
		button.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				downloadClick();
			}

		});
		return button;
	}

	private JScrollPane wrapWithScrollPane(Component component) {
		JScrollPane scrollPane = new JScrollPane(component);

		return scrollPane;
	}

	private ListSelectionListener mRemoteListSelectionListener = new ListSelectionListener() {

		@Override
		public void valueChanged(ListSelectionEvent e) {
			if (e.getValueIsAdjusting() == false) {
				mDownloadButton.setEnabled(mRemoteList.getSelectedIndex() >= 0);
			}
		}

	};

	protected abstract void search(String query);

	protected abstract void downloadClick();

	protected abstract void resumeClick();

	protected abstract void pauseClick();

	protected DownloadTableModel mTableModel = null;
	protected JTable mDownloadTable = null;
	protected JList mRemoteList = null;

	private TableRowSorter<DownloadTableModel> sorter;

	private JButton mDownloadButton;

	protected JTextField mSearch;

	private JTextArea mLog;

}
